﻿//  ------------------------------------------------------------------------------------
//  Copyright (c) Mustafa Kasap
//  All rights reserved. 
//  
//  Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this 
//  file except in compliance with the License. You may obtain a copy of the License at 
//  http://www.apache.org/licenses/LICENSE-2.0  
//  
//  THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
//  EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR 
//  CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR 
//  NON-INFRINGEMENT. 
// 
//  See the Apache Version 2.0 License for specific language governing permissions and 
//  limitations under the License.
//  ------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

using Windows.UI.Popups;

using Windows.Devices.Bluetooth;
using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth.GenericAttributeProfile;

using System.Collections.ObjectModel;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.ApplicationModel.Core;
using System.ComponentModel;

using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Table;

using Windows.System.Threading;

namespace TISensorTag
{
    public class AppSettings
    {
        ApplicationDataContainer localSettings;

        private string accname;
        private string acckey;
        private int interval;

        public AppSettings()
        {
            Object settingsValue;

            localSettings = ApplicationData.Current.LocalSettings;


            settingsValue = localSettings.Values["accountName"];

            if (settingsValue == null)
            {
                accountName = "tisensortag";
            }
            else
            {
                accountName = settingsValue as string;
            }


            settingsValue = localSettings.Values["accountKey"];

            if (settingsValue == null)
            {
                accountKey = "inGmCGADkTpY3IBr+nYgkAwQm8KpnXAYo+g7s1tDwQct30RCvZqmCVhy6AYD0PDjgFpTPaGQu0oOMh7951G74w==";
            }
            else
            {
                accountKey = settingsValue as string;
            }


            settingsValue = localSettings.Values["timerInterval"];

            if (settingsValue == null)
            {
                interval = 1000;
            }
            else
            {
                interval = (int)settingsValue;
            }
        }
        public string accountName
        {
            get { return accname;}
            set
            {
                accname = value;
                localSettings.Values["accountName"] = accname;
            }
        }
        public string accountKey 
        {
            get { return acckey; }
            set
            {
                acckey = value;
                localSettings.Values["accountKey"] = acckey;
            }
        }
        public int timerInterval 
        {
            get { return interval; }
            set
            {
                interval = value;
                localSettings.Values["timerInterval"] = interval;
            }
        }
    }

    public class SensorEntity : TableEntity
    {
        public SensorEntity()
        {
            this.PartitionKey = "1";
            this.RowKey = Guid.NewGuid().ToString();

            MeasurementTime = DateTime.Now;
            ThermometerAmbTemp = 0.0;
            ThermometerObjTemp = 0.0;
            AccelerometerX = 0.0;
            AccelerometerY = 0.0;
            AccelerometerZ = 0.0;
            HumidityRelHum = 0.0;
            HumidityRelTemp = 0.0;
            MagnetometerX = 0.0;
            MagnetometerY = 0.0;
            MagnetometerZ = 0.0;
            BarometerAmbPres = 0.0;
            BarometerAmbTemp = 0.0;
            GyroscopeX = 0.0;
            GyroscopeY = 0.0;
            GyroscopeZ = 0.0;
        }

        public DateTime MeasurementTime { get; set; }
        public double ThermometerAmbTemp { get; set; }
        public double ThermometerObjTemp { get; set; }
        public double AccelerometerX { get; set; }
        public double AccelerometerY { get; set; }
        public double AccelerometerZ { get; set; }
        public double HumidityRelHum { get; set; }
        public double HumidityRelTemp { get; set; }
        public double MagnetometerX { get; set; }
        public double MagnetometerY { get; set; }
        public double MagnetometerZ { get; set; }
        public double BarometerAmbPres { get; set; }
        public double BarometerAmbTemp { get; set; }
        public double GyroscopeX { get; set; }
        public double GyroscopeY { get; set; }
        public double GyroscopeZ { get; set; }
    }

    public class BLEDevice
    {
        private BluetoothLEDevice device;
        private string addressString;

        public BLEDevice(BluetoothLEDevice bled)
        {
            this.device = bled;
            addressString = device.BluetoothAddress.ToString("x012");
        }

        public string Name { get { return device.Name; } }

        public BluetoothLEDevice Core { get { return device; } }

        public override string ToString()
        {
            return device.Name;
        }
    }

    public class TISensor
    {
        protected string DATA = "";
        protected string CONF = "";
        protected string PERIOD = "";
        protected string CALI = "";

        protected byte sensorActivationByte = 1;

        protected TextBlock DisplayPanel = null;
        public GattDeviceService Service { get; set; }

        public TISensor(GattDeviceService svc, TextBlock tb)
        {
            this.Service = svc;
            this.DisplayPanel = tb;
        }

        protected async Task<byte[]> ReadUncachedSensorData(GattCharacteristic ch)
        {
            GattReadResult readResult = await ch.ReadValueAsync(BluetoothCacheMode.Uncached);
            if (readResult.Status == GattCommunicationStatus.Unreachable)
            {
                MessageDialog dialog = new MessageDialog("Sensor not connected or out of range");
                await dialog.ShowAsync();
            }

            var result = new byte[readResult.Value.Length];
            DataReader.FromBuffer(readResult.Value).ReadBytes(result);

            return result;
        }

        protected virtual void ExtractMeasurement(byte[] RawData)
        {
        }

        public virtual string GetDisplayValue()
        {
            return "...";
        }

        public virtual async void UpdateDisplayPanel(string dispVal)
        {
            try
            {
                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                    () =>
                    {
                        try { this.DisplayPanel.Text = dispVal; }
                        catch (Exception ex) { }
                    });
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
        }

        public virtual async void Enable()
        {
            try
            {
                // Init
                var configChar = this.Service.GetCharacteristics(Guid.Parse(CONF)).First();
                byte[] sensorData = new byte[] { sensorActivationByte };

                GattCommunicationStatus status = await configChar.WriteValueAsync(sensorData.AsBuffer());

                if (status != GattCommunicationStatus.Success)
                {
                    MessageDialog dialog = new MessageDialog("Cant access the sensor.");
                    await dialog.ShowAsync();
                }

                // SetCalback
                GattCharacteristic dataChar = this.Service.GetCharacteristics(Guid.Parse(DATA)).First();
                if (dataChar.CharacteristicProperties == (GattCharacteristicProperties.Read | GattCharacteristicProperties.Notify))
                {
                    dataChar.ValueChanged += this.dataValueChanged;
                    status = await dataChar.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

                    if (status != GattCommunicationStatus.Success)
                    {
                        MessageDialog dialog = new MessageDialog("Cant access the sensor.");
                        await dialog.ShowAsync();
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        public virtual async void Disable()
        {
            // Put in idle
            try
            {
                GattCharacteristic dataChar = this.Service.GetCharacteristics(Guid.Parse(DATA)).First();
                dataChar.ValueChanged -= this.dataValueChanged;

                var configChar = this.Service.GetCharacteristics(Guid.Parse(CONF)).First();
                byte[] sensorData = new byte[] { 0 };

                GattCommunicationStatus status = await configChar.WriteValueAsync(sensorData.AsBuffer());
            }
            catch (Exception ex)
            {
            }
        }

        public virtual async void dataValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
        {
            try
            {
                var res = await this.ReadUncachedSensorData(sender);

                this.ExtractMeasurement(res);

                string dispVal = this.GetDisplayValue();

                this.UpdateDisplayPanel(dispVal);
            }
            catch (Exception ex)
            {

            }
        }
    }

    public class TISensorThermometer : TISensor
    {
        public double ambTemp = 0.0;
        public double objTemp = 0.0;

        public TISensorThermometer(GattDeviceService svc, TextBlock tb)
            : base(svc, tb)
        {
            DATA = "f000aa01-0451-4000-b000-000000000000";
            CONF = "f000aa02-0451-4000-b000-000000000000";

            sensorActivationByte = 1;
        }

        protected override void ExtractMeasurement(byte[] RawData)
        {
            // Extract ambiant temperature
            this.ambTemp = BitConverter.ToUInt16(RawData, 2) / 128.0;

            // Extract object temperature
            int twoByteValue = BitConverter.ToInt16(RawData, 0);
            double Vobj2 = twoByteValue * 0.00000015625;
            double Tdie = this.ambTemp + 273.15;
            double S0 = 5.593E-14;	// Calibration factor
            double a1 = 1.75E-3;
            double a2 = -1.678E-5;
            double b0 = -2.94E-5;
            double b1 = -5.7E-7;
            double b2 = 4.63E-9;
            double c2 = 13.4;
            double Tref = 298.15;
            double S = S0 * (1 + a1 * (Tdie - Tref) + a2 * System.Math.Pow((Tdie - Tref), 2));
            double Vos = b0 + b1 * (Tdie - Tref) + b2 * System.Math.Pow((Tdie - Tref), 2);
            double fObj = (Vobj2 - Vos) + c2 * System.Math.Pow((Vobj2 - Vos), 2);
            double tObj = System.Math.Pow(System.Math.Pow(Tdie, 4) + (fObj / S), .25);
            this.objTemp = tObj - 273.15;
        }

        public override string GetDisplayValue()
        {
            string sAmbTemp = string.Format("Ambiant: {0:N1} °C", this.ambTemp);
            string sObjTemp = string.Format("Object: {0:N1} °C", this.objTemp);

            return sAmbTemp + "\n" + sObjTemp;
        }
    }

    public class TISensorAccelerometer : TISensor
    {
        public double x = 0.0;
        public double y = 0.0;
        public double z = 0.0;

        public TISensorAccelerometer(GattDeviceService svc, TextBlock tb)
            : base(svc, tb)
        {
            DATA = "f000aa11-0451-4000-b000-000000000000";
            CONF = "f000aa12-0451-4000-b000-000000000000";
            PERIOD = "f000aa13-0451-4000-b000-000000000000";

            sensorActivationByte = 1;
        }

        public override async void Enable()
        {
            try
            {
                // Init
                var periodChar = this.Service.GetCharacteristics(Guid.Parse(PERIOD)).First();
                byte[] sensorPeriod = new byte[] { 50 };  // unit is 10ms

                GattCommunicationStatus status = await periodChar.WriteValueAsync(sensorPeriod.AsBuffer());

                if (status != GattCommunicationStatus.Success)
                {
                    MessageDialog dialog = new MessageDialog("Cant access the sensor.");
                    await dialog.ShowAsync();
                }

                base.Enable();
            }
            catch (Exception ex)
            {

            }
        }

        protected override void ExtractMeasurement(byte[] RawData)
        {
            this.x = (double)(RawData[0] * 1.0) / 64.0;
            this.y = (double)(RawData[1] * 1.0) / 64.0;
            this.z = (double)(RawData[2] * 1.0) / 64.0;
        }

        public override string GetDisplayValue()
        {
            return string.Format("X: {0:N2} G\nY: {1:N2} G\nZ: {2:N2} G", this.x, this.y, this.z); 
        }
    }

    public class TISensorHumidity : TISensor
    {
        public double relHum = 0.0;
        public double relTemp = 0.0;

        public TISensorHumidity(GattDeviceService svc, TextBlock tb)
            : base(svc, tb)
        {
            DATA = "f000aa21-0451-4000-b000-000000000000";
            CONF = "f000aa22-0451-4000-b000-000000000000";

            sensorActivationByte = 1;
        }

        protected override void ExtractMeasurement(byte[] RawData)
        {
            int rawH = BitConverter.ToUInt16(RawData, 2);
            rawH &= ~0x0003; // clear bits [1..0] (status bits)
            this.relHum = -6.0 + 125.0 / 65536 * (double)rawH;

            int rawT = BitConverter.ToUInt16(RawData, 0);
            this.relTemp = -46.85 + 175.72 / 65536 * (double)rawT;
        }

        public override string GetDisplayValue()
        {
            return string.Format("{0:N2} %rH\n{1:N2} °C", this.relHum, this.relTemp);
        }
    }

    public class TISensorMagnetometer : TISensor
    {
        public double x = 0.0;
        public double y = 0.0;
        public double z = 0.0;

        public TISensorMagnetometer(GattDeviceService svc, TextBlock tb)
            : base(svc, tb)
        {
            DATA = "f000aa31-0451-4000-b000-000000000000";
            CONF = "f000aa32-0451-4000-b000-000000000000";
            PERIOD = "f000aa33-0451-4000-b000-000000000000";

            sensorActivationByte = 1;
        }

        public override async void Enable()
        {
            // Init
            try
            {
                var periodChar = this.Service.GetCharacteristics(Guid.Parse(PERIOD)).First();
                byte[] sensorPeriod = new byte[] { 50 };  // unit is 10ms

                GattCommunicationStatus status = await periodChar.WriteValueAsync(sensorPeriod.AsBuffer());

                if (status != GattCommunicationStatus.Success)
                {
                    MessageDialog dialog = new MessageDialog("Cant access the sensor.");
                    await dialog.ShowAsync();
                }

                base.Enable();
            }
            catch (Exception ex)
            {
            }
        }

        protected override void ExtractMeasurement(byte[] RawData)
        {
            this.x = BitConverter.ToInt16(RawData, 0) * (2000f / 65536f);
            this.y = BitConverter.ToInt16(RawData, 2) * (2000f / 65536f);
            this.z = BitConverter.ToInt16(RawData, 4) * (2000f / 65536f);
        }

        public override string GetDisplayValue()
        {
            return string.Format("X: {0:N2} uT\nY: {1:N2} uT\nZ: {2:N2} uT", this.x, this.y, this.z); 
        }
    }

    public class TISensorBarometer : TISensor
    {
        public double ambPres = 0.0;
        public double ambTemp = 0.0;

        // Calibration data
        UInt16 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
        Int16 c5 = 0, c6 = 0, c7 = 0, c8 = 0;

        public TISensorBarometer(GattDeviceService svc, TextBlock tb)
            : base(svc, tb)
        {
            DATA = "f000aa41-0451-4000-b000-000000000000";
            CONF = "f000aa42-0451-4000-b000-000000000000";
            CALI = "f000aa43-0451-4000-b000-000000000000";
            
            sensorActivationByte = 1;
        }

        public override async void Enable()
        {
            try
            {
                // Init, read calibration values first
                var configChar = this.Service.GetCharacteristics(Guid.Parse(CONF)).First();
                byte[] sensorData = new byte[] { 2 };

                GattCommunicationStatus status = await configChar.WriteValueAsync(sensorData.AsBuffer());

                if (status != GattCommunicationStatus.Success)
                {
                    MessageDialog dialog = new MessageDialog("Cant access the sensor.");
                    await dialog.ShowAsync();
                }

                GattCharacteristic caliChar = this.Service.GetCharacteristics(Guid.Parse(CALI)).First();
                GattReadResult readResult = await caliChar.ReadValueAsync(BluetoothCacheMode.Uncached);
                if (readResult.Status == GattCommunicationStatus.Unreachable)
                {
                    MessageDialog dialog = new MessageDialog("Sensor not connected or out of range");
                    await dialog.ShowAsync();
                }

                var result = new byte[readResult.Value.Length];
                DataReader.FromBuffer(readResult.Value).ReadBytes(result);

                // Calibration data
                c1 = BitConverter.ToUInt16(result, 0);
                c2 = BitConverter.ToUInt16(result, 2);
                c3 = BitConverter.ToUInt16(result, 4);
                c4 = BitConverter.ToUInt16(result, 6);
                c5 = BitConverter.ToInt16(result, 8);
                c6 = BitConverter.ToInt16(result, 10);
                c7 = BitConverter.ToInt16(result, 12);
                c8 = BitConverter.ToInt16(result, 14);

                base.Enable();
            }
            catch (Exception ex)
            {
            }
        }

        protected override void ExtractMeasurement(byte[] RawData)
        {
            Int16 Tr = BitConverter.ToInt16(RawData, 0);
            UInt16 Pr = BitConverter.ToUInt16(RawData, 2);

            Int64 s, o, pres, val;

            // Sensitivity
            s = (Int64)c3;
            val = (Int64)c4 * Tr;
            s += (val >> 17);
            val = (Int64)c5 * Tr * Tr;
            s += (val >> 34);

            // Offset
            o = (Int64)c6 << 14;
            val = (Int64)c7 * Tr;
            o += (val >> 3);
            val = (Int64)c8 * Tr * Tr;
            o += (val >> 19);

            // Pressure (Pa)
            pres = ((Int64)(s * Pr) + o) >> 14;
            this.ambPres = (double)pres / 100;



            val = ((Int64)(c1 * Tr) * 100);
            Int64 temp = (val >> 24);
            val = ((Int64)c2 * 100);
            temp += (val >> 10);
            this.ambTemp = ((double)temp) / 100;
        }

        public override string GetDisplayValue()
        {
            return string.Format("{0:N2} hP\n{1:N2} °C", this.ambPres, this.ambTemp);
        }
    }

    public class TISensorGyroscope : TISensor
    {
        public double x = 0.0;
        public double y = 0.0;
        public double z = 0.0;

        public TISensorGyroscope(GattDeviceService svc, TextBlock tb)
            : base(svc, tb)
        {
            DATA = "f000aa51-0451-4000-b000-000000000000";
            CONF = "f000aa52-0451-4000-b000-000000000000";

            sensorActivationByte = 7;
        }

        protected override void ExtractMeasurement(byte[] RawData)
        {
            this.y = BitConverter.ToInt16(RawData, 0) * (500f / 65536f) * -1;
            this.x = BitConverter.ToInt16(RawData, 2) * (500f / 65536f);
            this.z = BitConverter.ToInt16(RawData, 4) * (500f / 65536f);
        }

        public override string GetDisplayValue()
        {
            return string.Format("X: {0:N2} °/S\nY: {1:N2} °/S\nZ: {2:N2} °/S", this.x, this.y, this.z); 
        }
    }

    public sealed partial class MainPage : Page
    {
        private AppSettings appSettings = null;

        private static BLEDevice selectedBLEDevice = null;

        private static ThreadPoolTimer timerDataTransfer;
    
        private const string UUID_TEMP = "f000aa00-0451-4000-b000-000000000000";
        private const string UUID_ACCEL = "f000aa10-0451-4000-b000-000000000000";
        private const string UUID_HUMID = "f000aa20-0451-4000-b000-000000000000";
        private const string UUID_MAG = "f000aa30-0451-4000-b000-000000000000";
        private const string UUID_BAROM = "f000aa40-0451-4000-b000-000000000000";
        private const string UUID_GYRO = "f000aa50-0451-4000-b000-000000000000";

        TISensorThermometer sensorT = null;
        TISensorAccelerometer sensorA = null;
        TISensorHumidity sensorH = null;
        TISensorMagnetometer sensorM = null;
        TISensorBarometer sensorB = null;
        TISensorGyroscope sensorG = null;

        bool connected = false;

        public MainPage()
        {
            appSettings = new AppSettings();

            this.InitializeComponent();

            this.NavigationCacheMode = NavigationCacheMode.Required;
        }

        private async void dataTransmitterTimerTick(ThreadPoolTimer timer)
        {
            if (!connected)
                return;

            try
            {
                //CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key");
                CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=" + appSettings.accountName + ";AccountKey=" + appSettings.accountKey);

                // Create the table client.
                CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

                // Create the CloudTable object that represents the "people" table.
                CloudTable table = tableClient.GetTableReference("SensorData");
                await table.CreateIfNotExistsAsync();

                // Create a new customer entity.
                SensorEntity ent = new SensorEntity();

                ent.MeasurementTime = DateTime.Now;
                ent.ThermometerAmbTemp = sensorT.ambTemp;
                ent.ThermometerObjTemp = sensorT.objTemp;
                ent.MagnetometerX = sensorM.x;
                ent.MagnetometerY = sensorM.y;
                ent.MagnetometerZ = sensorM.z;
                ent.HumidityRelHum = sensorH.relHum;
                ent.HumidityRelTemp = sensorH.relTemp;
                ent.GyroscopeX = sensorG.x;
                ent.GyroscopeY = sensorG.y;
                ent.GyroscopeZ = sensorG.z;
                ent.BarometerAmbPres = sensorB.ambPres;
                ent.BarometerAmbTemp = sensorB.ambTemp;
                ent.AccelerometerX = sensorA.x;
                ent.AccelerometerY = sensorA.y;
                ent.AccelerometerZ = sensorA.z;

                // Create the TableOperation that inserts the customer entity.
                TableOperation insertOperation = TableOperation.Insert(ent);

                // Execute the insert operation.
                await table.ExecuteAsync(insertOperation);
            }
            catch (Exception ex)
            {
                MessageDialog dialog = new MessageDialog("Error sending to Azure: " + ex.Message);
                dialog.ShowAsync();
            }
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (e.Parameter != null)
            {
                selectedBLEDevice = e.Parameter as BLEDevice;

                if (selectedBLEDevice != null)
                {
                    foreach (var service in selectedBLEDevice.Core.GattServices)
                    {
                        RegisterDeviceService(service);
                    }
                }
            }
        }

        void RegisterDeviceService(GattDeviceService gds)
        {
            switch (gds.Uuid.ToString())
            {
                case UUID_TEMP:
                    sensorT = new TISensorThermometer(gds, thermometer);
                    break;
                case UUID_ACCEL:
                    sensorA = new TISensorAccelerometer(gds, accelerometer);
                    break;
                case UUID_HUMID:
                    sensorH = new TISensorHumidity(gds, humidity);
                    break;
                case UUID_MAG:
                    sensorM = new TISensorMagnetometer(gds, magnetometer);
                    break;
                case UUID_BAROM:
                    sensorB = new TISensorBarometer(gds, barometer);
                    break;
                case UUID_GYRO:
                    sensorG = new TISensorGyroscope(gds, gyroscope);
                    break;
            }
        }

        private void btnDevSel_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(BLEDevices), selectedBLEDevice);
        }

        private async void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            if (selectedBLEDevice == null)
            {
                MessageDialog dialog = new MessageDialog("First select a TISensorTag on the top device list to connect. (TISensorTags must be paired from Settings -> Bluetooth window prior to the selection.)");
                await dialog.ShowAsync();
                return;
            }

            btnConnect.IsEnabled = false;
            try
            {
                if (connected)
                {
                    sensorT.Disable();
                    sensorA.Disable();
                    sensorH.Disable();
                    sensorM.Disable();
                    sensorB.Disable();
                    sensorG.Disable();

                    btnConnect.Label = "Connect";
                    btnConnect.Icon = new SymbolIcon(Symbol.Add);
                    connected = false;
                }
                else
                {
                    sensorT.Enable();
                    sensorA.Enable();
                    sensorH.Enable();
                    sensorM.Enable();
                    sensorB.Enable();
                    sensorG.Enable();

                    btnConnect.Label = "Disconnect";
                    btnConnect.Icon = new SymbolIcon(Symbol.Remove);
                    connected = true;
                }
            }
            catch (Exception ex)
            {
            }

            btnConnect.IsEnabled = true;
        }

        private void btnDataTransfer_Click(object sender, RoutedEventArgs e)
        {
            timerDataTransfer = ThreadPoolTimer.CreatePeriodicTimer(dataTransmitterTimerTick, TimeSpan.FromMilliseconds(Convert.ToInt32(appSettings.timerInterval)));
        }

        private void btnSettings_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(Settings), appSettings);
        }
    }
}
